from rest_framework.viewsets import ModelViewSet
from tools.models import Event,Fault,Remind
from tools.serializers import EventSerializer,FaultSerializer,RemindSerializer
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import UserInfo
from django.conf import settings
import os
from django.http import FileResponse
#发送消息
from libs.dingding import dingtalk_msg
from libs.mail_notify import mail
from libs.weixin_notify import send_message_to_wechat
#django-apscheduler
from user.models import UserInfo
from datetime import datetime, timedelta
from cron.apps import scheduler  #使用apps.py里面的调度器实例

class EventViewSet(ModelViewSet):
    queryset = Event.objects.all()
    serializer_class = EventSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend]  # 指定过滤器
    search_fields = ('name',)  # 指定可搜索的字段
    filterset_fields = ('name',)   # 指定过滤的字段

    def create(self, request, *args, **kwargs):
        print(request.data)
        try:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
        except Exception as e:
            print(e)

        name = request.data.get('name')

        # 多对多
        user_id_list = request.data.get('user')
        event = Event.objects.get(name=name)
        event.user.clear()  #先清除再添加
        event.user.add(*user_id_list)
        res = {'code': 200, 'msg': '创建成功'}
        return Response(res)

    def update(self, request, *args, **kwargs):
        try:
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
        except Exception as e:
            print(e)

        name = request.data.get('name')

        # 多对多
        user_id_list = request.data.get('user')
        event = Event.objects.get(name=name)
        event.user.clear()  #先清除再添加
        event.user.add(*user_id_list)
        res = {'code': 200, 'msg': '更新成功'}
        return Response(res)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        res = {'code': 200, 'msg': '删除成功'}
        return Response(res)


class FaultViewSet(ModelViewSet):
    queryset = Fault.objects.all()
    serializer_class = FaultSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend]  # 指定过滤器
    search_fields = ('name',)  # 指定可搜索的字段
    filterset_fields = ('name',)   # 指定过滤的字段

    def create(self, request, *args, **kwargs):
        try:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)

            name = request.data.get('name')
            file_obj = request.FILES.get('file')
            current_path = os.path.join(settings.BASE_DIR,'static','files', file_obj.name)  # 当前文件存放的路径
            with open(current_path, 'wb') as f:
                for i in file_obj.chunks():  # 循环接受文件块
                    f.write(i)
            # 多对多
            user_id_list = str(request.data.get('user')).split(',')
            fault = Fault.objects.get(name=name)
            fault.user.clear()  # 先清除再添加
            fault.user.add(*user_id_list)
            Fault.objects.filter(name=name).update(
                upload=file_obj.name
            )
            data = {'url': file_obj.name}
            res = {'code': 200, 'msg': '创建成功','data':data}
        except Exception as e:
            res = {'code': 500, 'msg': '%s' %e}
        return Response(res)

    def update(self, request, *args, **kwargs):
        try:
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)

            name = request.data.get('name')
            file_obj = request.FILES.get('file')
            current_path = os.path.join('static','files', file_obj.name)  # 当前文件存放的路径
            with open(current_path, 'wb') as f:
                for i in file_obj.chunks():  # 循环接受文件块
                    f.write(i)
            # 多对多
            user_id_list = str(request.data.get('user')).split(',')
            fault = Fault.objects.get(name=name)
            fault.user.clear()  # 先清除再添加
            fault.user.add(*user_id_list)
            Fault.objects.filter(name=name).update(
                upload=file_obj.name
            )
            data = {'url': file_obj.name}
            res = {'code': 200, 'msg': '更新成功','data':data}
        except Exception as e:
            res = {'code': 500, 'msg': '%s' %e}
        return Response(res)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        res = {'code': 200, 'msg': '删除成功'}
        return Response(res)

class FaultDownFile(APIView):
    def get(self, request):
        file_name = request.query_params.get('file')
        file_path = os.path.join(settings.BASE_DIR, 'static', 'files', file_name)
        response = FileResponse(open(file_path, 'rb'))
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment; filename=%s' % file_name
        return response


class RemindViewSet(ModelViewSet):
    queryset = Remind.objects.all()
    serializer_class = RemindSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend]  # 指定过滤器
    search_fields = ('name',)  # 指定可搜索的字段
    filterset_fields = ('name',)   # 指定过滤的字段

    def create(self, request, *args, **kwargs):
        print(request.data)
        try:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
        except Exception as e:
            res = {'code': 500, 'msg': '%s' %e}
            return Response(res)

        name = request.data.get('name')

        # 多对多
        user_id_list = request.data.get('user')
        remind = Remind.objects.get(name=name)
        remind.user.clear()  #先清除再添加
        remind.user.add(*user_id_list)
        res = {'code': 200, 'msg': '创建成功'}
        return Response(res)

    def update(self, request, *args, **kwargs):
        try:
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
        except Exception as e:
            print(e)

        name = request.data.get('name')

        # 多对多
        user_id_list = request.data.get('user')
        remind = Remind.objects.get(name=name)
        remind.user.clear()  #先清除再添加
        remind.user.add(*user_id_list)
        res = {'code': 200, 'msg': '更新成功'}
        return Response(res)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        res = {'code': 200, 'msg': '删除成功'}
        return Response(res)


def notify(way,address,content):
    if way == 1:
        mail(address, content)
    elif way == 2:
        url = address
        dingtalk_msg(url, content)
    elif way == 3:
        webhook_url = address
        send_message_to_wechat(webhook_url, content)


class RemindEnableView(APIView):
    def put(self,request):
        print(request.data)

        status = request.data.get('status')
        name = request.data.get('name')
        user = request.data.get('user')
        dingding_webhook = request.data.get('dingding_webhook')
        weixin_webhook = request.data.get('weixin_webhook')
        last_datetime = request.data.get('last_datetime')
        advance = request.data.get('advance')
        way = int(request.data.get('way'))
        note = request.data.get('note')
        last_datetime = request.data.get('last_datetime')
        advance = int(request.data.get('advance'))
        #处理提醒时间
        # 将日期字符串转换为datetime对象
        date_obj = datetime.strptime(last_datetime, "%Y-%m-%d %H:%M:%S")
        # 从日期中减去10天
        new_date_obj  = date_obj - timedelta(days=advance)
        # 将新的日期对象转换回字符串格式
        remind_time = new_date_obj.strftime("%Y-%m-%d %H:%M:%S")
        #处理邮件
        email_list = []
        for i in user:
            if type(i) is int:  #判断是不是整形
                user_obj = UserInfo.objects.get(id=i)
                email_list.append(user_obj.email)
            else:    #否则是字典类型
                email_list.append(i['email'])
        email = ';'.join(email_list)
        #定义发送内容
        content = f'您有一个事项：{name}将要到达指定时间,详细内容：{note},记得及时处理哦！'
        #处理address
        if way == 1:
            address = email
        elif way == 2:
            address = dingding_webhook
        elif way == 3:
            address = weixin_webhook

        if status == 2:
            # 添加任务
            try:
                scheduler.add_job(notify, 'date', run_date=remind_time, id=name,args=[way,address,content], replace_existing=True)
                #如果没有运行再启动调度器，如果调度器之前没有被启动过，那么它将会开始执行所有已经添加并且没有被暂停的任务。
                if not scheduler.running:
                    scheduler.start()
                #恢复任务
                job = scheduler.get_job(name)
                if job:
                    job.resume()
                Remind.objects.filter(name=name).update(status=2)
                res = {'code': 200, 'msg': '启用成功'}
                return Response(res)
            except Exception as e:
                res = {'code': 500, 'msg': '%s' %e}
                return Response(res)
        else:
            # 暂停任务
            try:
                job = scheduler.get_job(name)
                if job:
                    job.pause()
                Remind.objects.filter(name=name).update(status=1)
                res = {'code': 200, 'msg': '关闭成功'}
                return Response(res)
            except Exception as e:
                res = {'code': 500, 'msg': '%s' % e}
                return Response(res)

